package com.jijunpeng.javafx.cipher.controller;

import com.jijunpeng.javafx.cipher.common.DialogUtil;
import com.jijunpeng.javafx.cipher.common.enums.CharsetEnum;
import com.jijunpeng.javafx.cipher.controller.api.BaseController;
import com.jijunpeng.javafx.cipher.persistence.PersistenceJson;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Pane;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import java.nio.charset.Charset;

/**
 * @author Ji Junpeng
 * @date 2019-11-30 15:07
 */
@Slf4j
@PersistenceJson(path = "$.main_inner_$hex")
public class HexController extends BaseController {

    @FXML
    private Pane hexRootPane;
    @FXML
    @PersistenceJson(path = "charsetComboBox", field = "value", getter = "getValue")
    @PersistenceJson(path = "charsetComboBox", field = "disabled", getter = "isDisabled")
    private ComboBox<CharsetEnum> charsetComboBox;
    @FXML
    @PersistenceJson(path = "leftTextArea", field = "text", getter = "getText")
    @PersistenceJson(path = "leftTextArea", field = "disabled", getter = "isDisabled")
    private TextArea leftTextArea;
    @FXML
    @PersistenceJson(path = "rightTextArea", field = "text", getter = "getText")
    @PersistenceJson(path = "rightTextArea", field = "disabled", getter = "isDisabled")
    private TextArea rightTextArea;

    @Override
    protected Pane getRootPane() {
        return hexRootPane;
    }

    @Override
    protected void initViewData() {
        ObservableList<CharsetEnum> charsetList = FXCollections.observableArrayList(CharsetEnum.values());
        charsetComboBox.setItems(charsetList);
        charsetComboBox.setValue(charsetList.get(0));
    }

    /**
     * string --encode--> hex
     */
    @FXML
    private void encode(ActionEvent actionEvent) {
        String inputStr = null;
        CharsetEnum charset = null;
        try {
            inputStr = leftTextArea.getText();
            charset = charsetComboBox.getValue();
            String outputStr = encodeStr(inputStr, charset.getCharset());
            rightTextArea.setText(outputStr);
            log.info("Hex encodeStr, inputStr:{}, charset:{}, outputStr:{}", inputStr, charset, outputStr);
        } catch (Exception e) {
            log.error("Hex encodeStr throw exception. inputStr:{}, charset:{}, e:", inputStr, charset, e);
            DialogUtil.showError(hexRootPane, "Hex 编码失败", "错误原因：" + e.getMessage());
        }
    }

    /**
     * string <--decode-- hex
     */
    @FXML
    private void decode(ActionEvent actionEvent) {
        String inputStr = null;
        CharsetEnum charset = null;
        try {
            inputStr = rightTextArea.getText();
            charset = charsetComboBox.getValue();
            String outputStr = decodeHex(inputStr, charset.getCharset());
            leftTextArea.setText(outputStr);
            log.info("Hex decodeHex, inputStr:{}, charset:{}, outputStr:{}", inputStr, charset, outputStr);
        } catch (DecoderException e) {
            log.error("Hex decodeHex throw exception. inputStr:{}, charset:{}, e:", inputStr, charset, e);
            DialogUtil.showError(hexRootPane, "Hex 解码失败", "错误原因：" + e.getMessage());
        }
    }

    private String encodeStr(String inputStr, Charset charset) {
        byte[] resultBytes = inputStr.getBytes(charset);
        return Hex.encodeHexString(resultBytes);
    }

    private String decodeHex(String inputStr, Charset charset) throws DecoderException {
        byte[] outputBytes = Hex.decodeHex(inputStr);
        return new String(outputBytes, charset);
    }
}
